package com.hzchendou.blog.demo.auth.config;

import com.hzchendou.blog.demo.auth.utils.RSAUtils;
import java.security.KeyPair;
import java.util.HashMap;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @Date: 2022-05-13 10:25
 * @since: 1.0
 */
@Slf4j
@Configuration
public class TokenConfig {

    @Value("${jwt.rsa.publickey}")
    private String publicKey;
    @Value("${jwt.rsa.privatekey}")
    private String privateKey;

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accessTokenConverter());

    }


    @Bean
    public JwtAccessTokenConverter accessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setKeyPair(keyPair()); //非对称秘钥
        return converter;
    }

    @Bean
    public KeyPair keyPair() {
        try {
            return RSAUtils.genKeyPair(publicKey, privateKey);
        } catch (Exception ex) {
            log.error("生成 KeyPair 失败", ex);
            System.exit(-1);
            return null;
        }
    }

    /**
     * JWT内容增强
     */
    @Bean
    public TokenEnhancer tokenEnhancer() {
        return (accessToken, authentication) -> {
            Map<String, Object> additionalInfo = new HashMap<>();
            User principal = (User)authentication.getUserAuthentication().getPrincipal();
            String username = principal.getUsername();
            additionalInfo.put("ex_username", username);
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
            return accessToken;
        };
    }
}
